/*******************************************************************************
*
*   FILE NAME:
*       Game.cpp - Game class implementation
*
*   DESCRIPTION:
*       Provides basic graphics device initialization, game logic, and rendering
*       code.
*
*******************************************************************************/
#include "Game.h"

#include <Psapi.h>
#include <tchar.h>

Game::Game( void )
    : mDone( FALSE ),
      mGameWindow( NULL, 800, 600 )
{
    tchar title[ 128 ];
    GetModuleFileName( NULL, title, sizeof( title ) );
    _tcsrchr( title, '.' )[ 0 ] = NULL;
    mGameWindow.SetTitle( _tcsrchr( title, '\\' ) + 1 );

    PresentationParameters params;
    params.BackBufferFormat = SURFACE_FORMAT_COLOR;
    params.BackBufferHeight = mGameWindow.GetHeight();
    params.BackBufferWidth = mGameWindow.GetWidth();
    params.DepthStencilFormat = DEPTH_FORMAT_DEPTH24_STENCIL8;
    params.DeviceWindowHandle = mGameWindow.GetHandle();
    params.IsFullScreen = FALSE;
    params.MultiSampleCount = 4;
    params.PresentationInterval = PRESENT_INTERVAL_DEFAULT;
    params.RenderTargetUsage = RENDER_TARGET_USAGE_DISCARD_CONTENTS;

    mGraphicsDevice = new GraphicsDevice( GraphicsAdapter::GetDefaultAdapter(), params );
}

Game::~Game( void )
{
    if( mGraphicsDevice != NULL )
    {
        delete mGraphicsDevice;
    }
}

void Game::Exit( void )
{
    mDone = TRUE;
}

void Game::Run( void )
{
    GameTime game_time;

    Initialize();
    LoadContent();

    mGameWindow.SetVisible( TRUE );
    
    LARGE_INTEGER query;
    float64 frequency;
    uint64 start_ticks;
    uint64 previous_ticks;
    uint64 current_ticks;

    QueryPerformanceFrequency( &query );
    frequency = float64( query.QuadPart ) / 10000000.0;

    QueryPerformanceCounter( &query );
    start_ticks = previous_ticks = query.QuadPart;

    BeginRun();
    while( !mDone && mGameWindow.Update() )
    {
        QueryPerformanceCounter( &query );
        current_ticks = query.QuadPart;

        if( uint64( float64( current_ticks - previous_ticks ) / frequency ) < TimeSpan::TicksPerSecond / 60 )
        {
            continue;
        }

        game_time.SetRunningSlowly( FALSE );
        game_time.SetTotalTime( uint64( float64( current_ticks - start_ticks ) / frequency ) );
        game_time.SetElapsedTime( uint64( float64( current_ticks - previous_ticks ) / frequency ) );
        previous_ticks = current_ticks;
        
        Update( game_time );
        Draw( game_time );
    }
    EndRun();
    
    UnloadContent();
}

GraphicsDevice& Game::GetGraphicsDevice( void )
{
    return *mGraphicsDevice;
}

GameWindow& Game::GetGameWindow( void )
{
    return mGameWindow;
}

void Game::Initialize( void )
{
    mDone = FALSE;
}

void Game::LoadContent( void )
{
}

void Game::BeginRun( void )
{
}

void Game::Update( const GameTime& game_time )
{
}
void Game::Draw( const GameTime& game_time )
{
    mGraphicsDevice->Clear( Color( 0.0f, 0.0f, 0.0f, 1.0f ) );
    mGraphicsDevice->Present();
}

void Game::EndRun( void )
{
}

void Game::UnloadContent( void )
{
}
